﻿#include "stdafx.h"
#include <llvm/IR/Module.h>
#include "AstCall.h"
#include "SiContext.h"
#include "ClassInstanceType.h"
#include "AstClass.h"
#include "modules.h"
#include "LLVMType.h"
#include "FunctionInstance.h"
#include "AstFunction.h"
#include "utility.h"
#include "AstPackage.h"
#include "CodeGenerate/CallGen.h"
using namespace std;

using namespace llvm;
extern std::unique_ptr<Module> module;
std::string make(const std::string& name, const std::vector< Parameter >& arguments) {
	std::string n = "Call " + name + "(";
	if (arguments.empty()) {
		n.push_back(')');
		return n;
	}

	for (auto i : arguments) {
		//if (i.value->type)
		//	n += i.value->type->name + " " + i.value->name + ",";
		//else if (i.type)
		//	n += i.type->name + " " + i.value->name + ",";
		//else
		//	n += i.value->name + ",";
	}
	n.pop_back();
	n.push_back(')');
	return n;
}


void AstCall::draw(std::ostream & os) {

	std::string n = make(name, arguments);
	dotLable(os, n);

	if (_func) {
		// dotPointTo(os, _func, false);
	}
}

using namespace llvm;

CodeGen * AstCall::makeGen(SiContext * parent)
{
	std::vector<std::pair<std::string, CodeGen*> > gens;
	// 预处理参数
	for (auto &i : arguments) {
		if (i.value) {
			auto x=i.value->makeGen(parent);
			gens.push_back( std::make_pair(i.name, x));
		}
		else {
			throw std::runtime_error("函数 " + name + " 的无参数");
		}
	}

	AstClass *c=parent->findClass(name);
	if (c) {	// 类初始化
		return c->makeNew(gens);
	}

	// 查找函数
	CodeGen* g = parent->makeCall(name, gens);
	if (g) return  g;

	auto* p = CLangModule::getFunction(name);

	// 尝试查找纯 C 函数
	
	if (!p) {
		auto m = module.get();
		p = m->getFunction(name);
	}
	if (!p) throw std::runtime_error("找不到匹配的函数：" + name);

	auto * ins=new FunctionInstance(p);
	ins->name = name;

	auto *call = new CallGen();
	call->function = ins;
	for (auto &i : gens) {
		call->params.push_back(i.second);
	}
	return call;
}





